#ifndef APPLICATION_H
#define APPLICATION_H

#include "VideoDevice.h"
#include "Input.h"
#include "GUI.h"
#include "SoundManager.h"
#include "Timer.h"

namespace Cvekas {

/// Base class for Cvekas applications
class Application
{
public:
	/// Constructor
	/// \param instance Handle to aplication instnce, supplied by WinMain
	/// \param name %Application name
	/// \param log_filename Log file name
	Application(HINSTANCE instance, const std::string& name, const std::string& log_filename);
	
	/// Destructor
	virtual ~Application();

	/// Must initialize window and video_device, called before any other virtual function.
	virtual void initVideoDevice() = 0;
	/// Called before entering main loop, useful for loading resources.
	virtual void init() {};
	/// Called before exiting application.
	virtual void close() {};
	/// Called once every frame, before render(). Return value false breaks out of main loop.
	virtual bool update() = 0;
	/// Called once every frame. Return value false breaks out of main loop.
	virtual bool render() = 0;

	/// Enters main loop
	void run();

	/// Assigns GUI object to Engine monostate
	void setGUI(GUIPtr gui);

protected:
	WindowPtr window;

	VideoDevicePtr video_device;
	SoundManagerPtr sound_manager;
	InputPtr input;
	GUIPtr gui; // HACK: make this read-only
	SettingsPtr settings;

	RendererPtr main_renderer;
	TextureManagerPtr texture_manager;
	GpuBufferManagerPtr gpu_buffer_manager;
	EffectManagerPtr effect_manager;

	const HINSTANCE instance;
	const std::string name;
};

} // namespace

#endif
